/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief Parameter XML container header.
 * \author Matthieu Myrsky <matthieu.myrsky@tkk.fi>
 *
 * $Id: ParameterXML.hpp,v 1.2 2009-09-22 08:52:14 morsko Exp $
 *
 */
#ifndef _MACI_PARAMETERXML_HPP_
#define _MACI_PARAMETERXML_HPP_
#include "ParameterTypes.hpp"
#include <string>
#include <vector>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <assert.h>


namespace MaCI {
  namespace Parameter {
    struct TParameterInfo{
      TParameterInfo(std::string aKey ="",
                     std::string aDescription ="",
                     std::string aCurrentValue ="",
                     std::string aValidValues ="",
                     std::string aValidValuesRegExp="")
        : key(aKey),
          description(aDescription),
          currentValue(aCurrentValue),
          validValues(aValidValues),
          validValuesRegExp(aValidValuesRegExp){}

      std::string key;
      std::string description;
      std::string currentValue;
      std::string validValues;
      std::string validValuesRegExp;
    };
        
    typedef std::vector<TParameterInfo> TParameterInfoArray;

    struct TParam{
      TParam(std::string aKey="",
             std::string aValue ="")
        :key(aKey),
         value(aValue){}

      std::string key;
      std::string value;

    };
    /** Container datatype.
     *
     * This result container can carry the following types:
     */
    enum EParamType {
      KUnknown,           ///< Result set type is currently unassigned/unknown
      KTypeInfoArray,     ///< Contains TParamInfoArray
      KTypeParam          ///< Contains param
    };

    /** Parameter encapsulation class.
     *
     * This class is intended for handling Parameter data transfer
     * between GIMnet nodes. Its interface is capable of storing and
     * returning Parameter data, while keeping it in compatible XML
     * format while in transit. The storage format XML is designed to
     * be as small and fast-to-interpret as possible to keep the
     * overhead of transferring over GIMnet in minimum.
     *
     * This class is designed to act as base-class for application
     * specific Parameter interpretations.
     *
     *
     */
    class CParameterXML{

    public:
      /** Default empty constructor.
       *
       */
      CParameterXML(void);
      
      
      ~CParameterXML(void);

      void Reset(void);

      /** Encode current class contents to internal XML result.
       *
       * This function converts the current memory representation of
       * SQL data to XML format. The XML string is stored in internal
       * XML string data result. Stored data can be fetched anytime
       * by calling GetXMLData() function.
       *
       * @return                'true' when conversion was succesfull,
       *                        'false' on any error.
       */
      bool EncodeParameterXML(void);

      bool EncodeParameterXML(std::string &aXMLData);

      /** Decode a XML datastring containing Parameter compatible XML.
       *
       *  @return                'true' when given data was succesfully decoded as
       *                         SQLResult compatible XML. 'false' on any error.
       */
      bool DecodeParameterXML(const std::string &aXMLData);

      void SetParameterInfoArray(TParameterInfoArray aParameterInfoArray);

      void SetParameter(TParam aParam);

      bool GetParameters(TParameterInfoArray &aParameterInfoArray);

      bool GetParameter(TParam &aParam);

      /** Return reference to internal XMLdata-result std::tring.
       * 
       * @return                Const reference to internal XMLData string.
       */
      const std::string &GetXMLData(void) const { return iXMLData; }


      void PrintDecodedData(unsigned int level);
    private:
      bool EncodeInfoArray(std::string &aXMLData);

      bool EncodeParam(std::string &aXMLData);

      bool DecodeInfoArray(xmlDocPtr docp, xmlNodePtr nodep);

      bool DecodeParam(xmlDocPtr docp, xmlNodePtr nodep);

      std::string iXMLData;
      EParamType iParamType;
      bool iArraySet;
      bool iParamSet;
      TParameterInfoArray iArray;
      TParam iParam;

    };
  }

}



#endif
